package common.mq.register.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;

import com.google.gson.reflect.TypeToken;

import common.mq.persistence.po.DBResult;
import common.mq.persistence.po.TableName;
import common.mq.persistence.service.IPersistenceService;
import common.mq.register.po.Consumer;
import common.mq.register.po.Event;
import common.mq.register.po.MessageBase;
import common.mq.register.service.IListener;
import common.mq.register.service.IRegisterService;
import common.mq.util.FileUtil;

public class RegisterServiceImpl implements IRegisterService {

	private List<String> callers = new ArrayList<String>();
	private Map<String, MessageBase> messageBases = new HashMap<String, MessageBase>(); // category-messageBase
	private Map<String, ArrayList<Consumer>> msgConsumers = new HashMap<String, ArrayList<Consumer>>(); // category-consumerList
	private Map<Integer, Consumer> consumers = new HashMap<Integer, Consumer>(); // consumerId-Consumer
	
	private List<IListener> listeners = new ArrayList<IListener>();
	
	@Autowired
	private IPersistenceService persistenceService;

	@Override
	public void setPersistenceService(IPersistenceService persistenceService) {
		this.persistenceService = persistenceService;
	}

	@Override
	public void setListeners(List<IListener> listeners) {
		this.listeners = listeners;
	}

	/**
	 * 判断该消息类型是否已注册
	 * 
	 * @param category
	 * @return
	 */
	@Override
	public boolean hasRegister(String category) {
		return messageBases.containsKey(category);
	}

	/**
	 * 根据消息类型查找元消息
	 * 
	 * @param category
	 * @return
	 */
	@Override
	public MessageBase getMessageBase(String category) {
		return messageBases.get(category);
	}

	/**
	 * 查找元消息对应的消费者列表（消息类型与元消息一一对应）
	 * 
	 * @param category
	 * @return
	 */
	@Override
	public ArrayList<Consumer> getConsumers(String category) {
		return msgConsumers.get(category);
	}
	
	@Override
	public Consumer getConsumer(Integer consumerId) {
		return consumers.get(consumerId);
	}

	@Override
	public boolean isUidExist(String uid) {
		return callers.contains(uid);
	}

	@Override
	public void notifyAll(Object param, Event e) {
		for (IListener l : listeners) {
			l.update(param, e);
		}

	}

	@Override
	public boolean addCaller(String caller) {
		// TODO 注册器管理后台功能，暂不实现
		return false;
	}

	@Override
	public boolean removeCaller(String caller) {
		// TODO 注册器管理后台功能，暂不实现
		return false;
	}

	@Override
	public boolean addMessageBase(MessageBase mb) {
		// TODO 注册器管理后台功能，暂不实现
		return false;
	}

	@Override
	public boolean removeMessageBase(String category) {
		// TODO 注册器管理后台功能，暂不实现
		return false;
	}

	@Override
	public boolean addConsumer(Consumer consumer) {
		// TODO 注册器管理后台功能，暂不实现
		return false;
	}

	@Override
	public boolean removeConsumer(Integer consumerId) {
		// TODO 注册器管理后台功能，暂不实现
		return false;
	}

	/**
	 * 暂时通过配置文件读取 注册器管理后台实现后从数据库读取
	 */
	@Override
	public void loadData() {
        
		loadCaller();
		loadMessageBase();
		loadConsumer();
		loadMsgConsumer();
		System.out.println();
	}

	private void loadCaller(){
		Map<String, String> callerMap = persistenceService.recover(TableName.CALLER.getName(),
				String.class, String.class);
		Set<Map.Entry<String, String>> set = callerMap.entrySet();
		for(Map.Entry<String, String> entry : set){
			callers.add((String)entry.getValue());
		}
	}
	
	private void loadMessageBase(){
		messageBases = persistenceService.recover(TableName.MESSAGEBASE.getName(),
				String.class, MessageBase.class);
	}
	
	private void loadMsgConsumer(){
		List<DBResult> mbConsumerList = persistenceService.getDBResultList(TableName.MBCONSUMER.getName());
		for(DBResult r : mbConsumerList){
			ArrayList<Consumer> cs = null;
			String category = r.getsKey();
			if(msgConsumers.containsKey(category)){
				cs = msgConsumers.get(category);
			}else{
				cs = new ArrayList<Consumer>();
			}
			Consumer consumer = this.consumers.get(Integer.valueOf(r.getsValue()));
			cs.add(consumer);
			this.msgConsumers.put(category, cs);
		}
	}
	
	public void loadConsumer(){
		consumers = persistenceService.recover(
				TableName.CONSUMER.getName(), Integer.class, Consumer.class);
	}
}
